﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace GeneticAlgorythm.Algorythm
{
    public class Individual
    {
        private Chromosome _chromosome;
        private int _currentAge = 0;
        private int _deathAge = 0;
        private double _objectiveFunctionValue;
        private bool _hasFunctionValue = false;


        public Individual(Chromosome chromosome, int deathAge = 0)
        {
            _chromosome = chromosome;
            _deathAge = deathAge;
        }
        public void mutate(int numberOfMutations)
        {
            for (int i = 0; i < numberOfMutations; i++)
            {

                int startIndex = RandomGenerator.getInstance().generateRandomIntegerFromZeroTo(_chromosome.getSize());
                int endIndex = RandomGenerator.getInstance().generateRandomIntegerFromZeroTo(_chromosome.getSize());

                while(startIndex.Equals(endIndex))
                    endIndex = RandomGenerator.getInstance().generateRandomIntegerFromZeroTo(_chromosome.getSize());

                switchGenes(startIndex, endIndex);

            }

        }
        public void makeOlder()
        {
            _currentAge++;
        }
        public Chromosome getChromosome()
        {
            return _chromosome;
        }
        public void setObjectiveFunctionValue(double value)
        {
            _objectiveFunctionValue = value;
            _hasFunctionValue = true;
        }
        public double getObjectiveFunctionValue()
        {
            return _objectiveFunctionValue;
        }
        public bool isTooOld()
        {
            if (_deathAge.Equals(0)) return false;
            if (_currentAge >= _deathAge) return true;
            return false;

        }

        public bool hasObjectiveFunctionValue()
        {
            return _hasFunctionValue;
        }
        public override bool Equals(Object obj)
        {
            if (getChromosome().Equals(((Individual)obj).getChromosome()))
                return true;
            return false;
        }

        public void setDeathAge(int deathAge)
        {
            _deathAge = deathAge;
        }

        public override string ToString()
        {
            return _chromosome.ToString();
        }

        private void switchGenes(int startIndex, int endIndex){
            int startGene = (int)_chromosome.getGene(startIndex);
            _chromosome.setGene(startIndex, _chromosome.getGene(endIndex));
            _chromosome.setGene(endIndex, startGene);
        }

    }
}
